package com.ozo.boot.auth.token;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.ozo.boot.auth.constant.RedisKeyConstant;
import com.ozo.boot.auth.exception.AuthExceptionEnum;
import com.ozo.boot.auth.log.LoginLogEvent;
import com.ozo.boot.auth.log.LoginLogUtil;
import com.ozo.boot.auth.pojo.dto.LoginDTO;
import com.ozo.boot.common.base.constant.StatusEnum;
import com.ozo.boot.common.base.model.LoginUser;
import com.ozo.boot.common.base.model.ResultVO;
import com.ozo.boot.common.core.exception.ServiceException;
import com.ozo.boot.manage.pojo.vo.SysUserInfoVO;
import com.ozo.boot.manage.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 手机号登录
 * </p>
 *
 * @author qiangesoft
 * @since 2024-07-11
 */
@RequiredArgsConstructor
@Component("PHONENUM")
public class PhoneNumTokenGranter extends AbstractTokenGranter {

    private final ISysUserService sysUserService;

    private final RedisTemplate<String, String> redisTemplate;

    @Override
    public LoginUser login(LoginDTO loginDTO) {
        // 验证码校验
        String mobile = loginDTO.getMobile();
        String smsCode = loginDTO.getSmsCode();
        String code = redisTemplate.opsForValue().get(RedisKeyConstant.SMS_LOGIN + mobile);
        if (code != null) {
            redisTemplate.delete(RedisKeyConstant.SMS_LOGIN + mobile);
        }
        if (!smsCode.equals(code)) {
            SpringUtil.publishEvent(new LoginLogEvent(LoginLogUtil.fail(mobile, JSONUtil.toJsonStr(ResultVO.fail(AuthExceptionEnum.SMS_CODE_ERROR)))));
            throw new ServiceException(AuthExceptionEnum.SMS_CODE_ERROR);
        }

        SysUserInfoVO sysUserVO = sysUserService.getByMobile(loginDTO.getMobile());
        if (sysUserVO == null) {
            SpringUtil.publishEvent(new LoginLogEvent(LoginLogUtil.fail(mobile, JSONUtil.toJsonStr(ResultVO.fail(AuthExceptionEnum.MOBILE_NOT_EXISTS)))));
            throw new ServiceException(AuthExceptionEnum.MOBILE_NOT_EXISTS);
        }

        if (StatusEnum.DISABLE.getCode().equals(sysUserVO.getStatus())) {
            SpringUtil.publishEvent(new LoginLogEvent(LoginLogUtil.fail(mobile, JSONUtil.toJsonStr(ResultVO.fail(AuthExceptionEnum.ACCOUNT_DISABLED)))));
            throw new ServiceException(AuthExceptionEnum.ACCOUNT_DISABLED);
        }

        return this.doLogin(sysUserVO, false);
    }

}
